package com.ruoyi.house.service.webmagic;


import com.ruoyi.house.constants.Constants;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.DataNode;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Json;
import us.codecraft.webmagic.selector.Selectable;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;


/**
 * @author Zln
 * @version 2018-12-24 14:47
 *https://blog.csdn.net/chfenix/article/details/85230384
 * 饿了么店铺 爬虫
 */

public class BuildingProcessorV2 implements PageProcessor {

    Logger logger = LoggerFactory.getLogger(getClass());

    int districtNum = 2;
    Object object = new Object();

    private Site site = Site.me().setRetryTimes(10).setSleepTime(1000)
            .setTimeOut(1000*20)
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71")
//            .setUserAgent("Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; LCJB; rv:11.0) like Gecko")
//            .setUserAgent("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)")
            .addCookie("JSESSIONID","0FECF1E22B6F4C720319A5703AE0B948")
            .addCookie("clientlanguage","zh_CN")
//            .setSleepTime(200)
            .addHeader("Pragma","no-cache");

    private String longitude;
    private String latitude;
    private Boolean crawlMenu = false; // 是否抓取菜单信息
    private WebDriver webDriver;
//    private List<WebDriver> webDriverList;
    private ArrayBlockingQueue<WebDriver> webDriverQueue ;
//    private ExecutorService pool = Executors.newFixedThreadPool(1000);
    /**
     * 饿了么店铺爬虫实例化方法
     * @param longitude	 经度
     * @param latitude	 纬度
     * @param crawlMenu 是否抓取菜单
     */
    public BuildingProcessorV2(String longitude, String latitude,
                               Boolean crawlMenu) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.crawlMenu = crawlMenu;
//        this.webDriver = getWebDriver();
    }
    public BuildingProcessorV2(String longitude, String latitude,
                               Boolean crawlMenu, WebDriver webDriver) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.crawlMenu = crawlMenu;
        this.webDriver = webDriver;
        this.webDriverQueue = new ArrayBlockingQueue<WebDriver>(10);
        for (int i = 0;i<10;i++){
            WebDriver driver = getWebDriver();
            this.webDriverQueue.add(driver);
        }
    }

    public BuildingProcessorV2(String longitude, String latitude,
                               Boolean crawlMenu, ArrayBlockingQueue<WebDriver> webDriverQueue) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.crawlMenu = crawlMenu;
        this.webDriverQueue = webDriverQueue;
    }

    public BuildingProcessorV2(ArrayBlockingQueue<WebDriver> webDriverQueue) {
    }

    public BuildingProcessorV2() {

    }

    @Override
    public void process(Page page) {
//        logger.info("page.getUrl:{}",JSON.toJSONString(page.getUrl()));
        logger.info("process page:{}",page.getUrl().get());
        // H5列表数据 小区信息
        if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/index+")
                .match()) {
            logger.info("解析小区列表数据");
//            logger.debug(page.getRawText());
            extractDistrict(page);
            //楼栋信息
        } else if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/show.shtml+")
                .match()){
            //https://124.128.246.22:8090/onsaling/show.shtml?prjno=0f06af26-cfa5-4945-a241-3690f22f00f9
            //https://124.128.246.22:8090/onsaling/show.shtml?prjno=a153f95b-4b0a-480f-badb-70ad6c7cb14a
            //next page
            //https://124.128.246.22:8090/onsaling/show_2.shtml?prjno=a153f95b-4b0a-480f-badb-70ad6c7cb14a
            logger.info("解析building");
//            logger.debug(page.getRawText());
            extractBuilding(page);
        }
        else if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/bshow.shtml+")
                .match()){
            logger.info("解析building detail");
//            logger.debug(page.getRawText());
            extractBuildingDetail(page);
        }else if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/yearsale+")
                .match()){
            logger.info("解析yearsale");
//            logger.debug(page.getRawText());
            extractYearSale(page);
        }else if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/viewhouse+")
                .match()){
//            if (true){
//                return;
//            }
            logger.info("解析viewhouse data");
//            logger.info(page.getRawText());
//            ChromeDriver webDriver = (ChromeDriver)getWebDriver();

            try {
                WebDriver driver = webDriverQueue.take();
                extractedViewDivV2(driver,page);
                webDriverQueue.put(driver);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            synchronized (object){
//                extractedViewDiv(page);
//            }

//            Alert javascriptConfirm = webDriver.switchTo().alert();
//            javascriptConfirm.accept();
        }else if (page.getUrl()
                .regex("https://124.128.246.22:8090/onsaling/viewDiv+")
                .match()) {
            Json json = page.getJson();
//            ViewDiv viewDiv = json.toObject(ViewDiv.class);
            page.putField("type", Constants.ProcessType.VIEWDIV);
            page.putField("viewDiv", json);
            page.putField("viewDivUrl", page.getUrl().get());
        }else if (page.getUrl()
                .regex("https://124.128.246.22:8090/")
                .match()){
            logger.info("解析agency data");
//            logger.debug(page.getRawText());
            extractedAgency(page);
        }else {
            Selectable selectable = page.getUrl();
            logger.error("getUrl:",selectable.get());
        }
    }
    private void extractedViewDivV2(WebDriver webDriver,Page page) {
        try {
            Thread.sleep(2000);
            webDriver.get(page.getUrl().get());
            Thread.sleep(2000);
//            System.out.println(webDriver.switchTo().alert().getText());
            webDriver.switchTo().alert().accept();
            Thread.sleep(3000);
            String pageSource = webDriver.getPageSource();
//            logger.info("pageSource:"+pageSource);
            Html html = new Html(pageSource);
            Element element = html.getDocument().body().getElementById("bussTable");
            Elements valignElements = element.getElementsByAttribute("valign");
            String floor = "";
            for (Element ele : valignElements){
                Elements styles = ele.getElementsByAttribute("style");
                if (styles.size()%2 == 1){
                    Element first = styles.first();
                    if (StringUtils.isNoneBlank(first.text())){
                        floor = first.text();
                    }
                }
                for (Element td : styles){
                    String id = td.attr("id");
                    if (StringUtils.isEmpty(id)){
                        continue;
                    }
                    String houseNo = td.text().replace("__","-").replace("--","-");
//                    logger.info("id:{},houseNo:{}",id,houseNo);
                    String url = "https://124.128.246.22:8090/onsaling/viewDiv.shtml?fid="+id+"&rd="+new Date()+"&floor="+floor+"&houseNo="+houseNo;
                    logger.info("---------viwDiv:{}",url);
//                    page.addTargetRequest(url);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
//                webDriver.quit();
        }finally {
        }
    }

    private void extractedViewDiv(Page page) {
        try {
            Thread.sleep(2000);
            webDriver.get(page.getUrl().get());
            Thread.sleep(2000);
//            System.out.println(webDriver.switchTo().alert().getText());
            webDriver.switchTo().alert().accept();
            Thread.sleep(3000);
            String pageSource = webDriver.getPageSource();
//            logger.info("pageSource:"+pageSource);
            Html html = new Html(pageSource);
            Element element = html.getDocument().body().getElementById("bussTable");
            Elements valignElements = element.getElementsByAttribute("valign");
            String floor = "";
            for (Element ele : valignElements){
                Elements styles = ele.getElementsByAttribute("style");
                if (styles.size()%2 == 1){
                    Element first = styles.first();
                    if (StringUtils.isNoneBlank(first.text())){
                        floor = first.text();
                    }
                }
                for (Element td : styles){
                    String id = td.attr("id");
                    if (StringUtils.isEmpty(id)){
                        continue;
                    }
                    String houseNo = td.text().replace("__","-").replace("--","-");
//                    logger.info("id:{},houseNo:{}",id,houseNo);
                    String url = "https://124.128.246.22:8090/onsaling/viewDiv.shtml?fid="+id+"&rd="+new Date()+"&floor="+floor+"&houseNo="+houseNo;
                    logger.info("---------viwDiv:{}",url);
//                    page.addTargetRequest(url);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
//                webDriver.quit();
        }finally {
        }
    }

    private WebDriver getWebDriver() {
        ChromeOptions options = new ChromeOptions();

        Properties props = System.getProperties();
        //操作系统名称
        String osName = props.getProperty("os.name");
        if (osName.toLowerCase().contains("windows")){
        System.setProperty("webdriver.chrome.driver","E:\\chromedriver.exe");
                    options.setBinary("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe");
        }else {
            System.setProperty("webdriver.chrome.driver","/home/zhoulipeng/IdeaProjects/jeesns/hello-web/src/main/resources/drivers/chromedriver");
            options.setBinary("/opt/apps/cn.google.chrome/files/google-chrome");
        }
//            WebDriver webDriver = new ChromeDriver();

        WebDriver webDriver = new ChromeDriver(options);
//        webDriver.manage().window().maximize();

        return webDriver;
    }

    private void extractedAgency(Page page) {
        Html html = page.getHtml();
        Elements elements = html.getDocument().body().getElementsByClass("list-data");
        if(elements.size() == 0){
            return;
        }
        elements = elements.get(0).getElementsByAttribute("style");
//            List<List<String>> agencyList = new ArrayList<>();
        int count = 1;
        List<String> agency = new ArrayList<>();
        for (Element liElement : elements){
//                Elements attributeElements = listEle.getElementsByAttribute("title");
            String text = liElement.text();
            agency.add(text);
//            logger.error("agency text:{}",text);

        }
        page.putField("type", Constants.ProcessType.AGENCY);
        page.putField("agency", agency);
    }

    private void extractYearSale(Page page) {
        Html html = page.getHtml();
        Elements elements = html.getDocument().body().getElementsByClass("list-main");
        List<List<String>> yearDataList = new ArrayList<>();
        int count = 1;
        for (Element liElement : elements){
            Elements attributeElements = liElement.getElementsByAttribute("style");
            List<String> yearData = new ArrayList<>();
            for (Element wdEle : attributeElements){
                String text = wdEle.text();
                yearData.add(text);
//                logger.error("yearData text:{}",text);
            }
            yearDataList.add(yearData);

        }
        page.putField("type", Constants.ProcessType.YEARSALE);
        page.putField("yearDataList", yearDataList);
    }

    private void extractBuildingDetail(Page page) {
        int textNum = 2;
        List<String> textList = new ArrayList<>();
        Html html = page.getHtml();
        Elements baseElements = html.getDocument().body().getElementsByAttribute("width");
        String baseUrl = "";
//            for (Element base : baseElements){
//                String text = base.text();
//                baseUrl = base.baseUri();
//                if (textNum%2 != 0){
//                    textList.add(text);
//                    System.out.println("text:"+text);
//                }
//                textNum++;
//            }
        baseElements = html.getDocument().body().getElementsByClass("massage_bg");
        for (Element base : baseElements){
            String text = base.text();
            if (textNum%2 != 0){
                textList.add(text);
//                System.out.println("text:"+text);
            }
            textNum++;
            baseUrl = base.baseUri();
        }
        //massage_bg
        textList.add(baseUrl);
        Elements elements = html.getDocument().body().getElementsByClass("list-main");
        List<List<String>> buildingDetailList = new ArrayList<>();

        for (Element listEle : elements){
//                Elements attributeElements = listEle.getElementsByAttribute("title");
            List<String> building = new ArrayList<>();
            Elements attributeElements = listEle.getElementsByClass("ellipsis");
            for (Element attributeEle : attributeElements){
                String title = attributeEle.attr("title");
                Elements aElements = attributeEle.getElementsByAttribute("href");
                String value = attributeEle.text();
                String tagName = attributeEle.html();
                List<DataNode> dataNodes = attributeEle.dataNodes();
                building.add(value);
//                    logger.error("value:{}",value);
//                    logger.error("title:{}",title);
            }
            building.addAll(textList);
            buildingDetailList.add(building);
        }
        page.putField("type", Constants.ProcessType.BUILDINGDETAIL);
        page.putField("buildingDetailList", buildingDetailList);
    }

    private void extractBuilding(Page page) {
        int textNum = 2;
        List<String> textList = new ArrayList<>();
        Html html = page.getHtml();
        Elements baseElements = html.getDocument().body().getElementsByAttribute("width");
        String baseUrl = "";
        for (Element base : baseElements){
            String text = base.text();
            baseUrl = base.baseUri();
            if (textNum%2 != 0){
                textList.add(text);
//                System.out.println("text:"+text);
            }
            textNum++;
        }
        textList.add(baseUrl);
        Elements elements = html.getDocument().body().getElementsByClass("list-main");
        List<List<String>> buildingList = new ArrayList<>();

        for (Element listEle : elements){
//                Elements attributeElements = listEle.getElementsByAttribute("title");
            List<String> building = new ArrayList<>();
            Elements attributeElements = listEle.getElementsByClass("ellipsis");
            for (Element attributeEle : attributeElements){
                String title = attributeEle.attr("title");
                Elements aElements = attributeEle.getElementsByAttribute("href");
                String value = attributeEle.text();
                String tagName = attributeEle.html();
                List<DataNode> dataNodes = attributeEle.dataNodes();
                building.add(title);
//                    logger.error("value:{}",value);
                for (Element eHref : aElements){
                    String buildingUrl = eHref.attr("href");
                    String targetUrl = "https://124.128.246.22:8090" + buildingUrl;
//                    page.addTargetRequest(targetUrl);
//                    logger.error("href:{}",buildingUrl);
                    building.add(buildingUrl);

                }
//                    logger.error("title:{}",title);
            }
            building.addAll(textList);
            buildingList.add(building);
        }
        page.putField("type", Constants.ProcessType.BUILDING);
        page.putField("buildingList", buildingList);
    }

    private void extractDistrict(Page page) {
        Html html = page.getHtml();
        Elements elements = html.getDocument().body().getElementsByClass("list-main");
        List<List<String>> districtList = new ArrayList<>();

        for (Element listEle : elements){
//                Elements attributeElements = listEle.getElementsByAttribute("title");
            List<String> district = new ArrayList<>();
            Elements attributeElements = listEle.getElementsByClass("ellipsis");
            for (Element attributeEle : attributeElements){
                String title = attributeEle.attr("title");
                Elements aElements = attributeEle.getElementsByAttribute("href");
                String value = attributeEle.text();
                String tagName = attributeEle.html();
                List<DataNode> dataNodes = attributeEle.dataNodes();
                if (value.contains(".")){
                    district.add(title);
                }else {
                    district.add(value);
                }
//                    logger.error("value:{}",value);
                for (Element eHref : aElements){
                    String buildingUrl = eHref.attr("href");
                    String targetUrl = "https://124.128.246.22:8090" + buildingUrl;
//                    page.addTargetRequest(targetUrl);
//                        districtNum++;
//                        logger.error("href:{}",buildingUrl);
                    district.add(targetUrl);
                }
//                    logger.error("title:{}",title);
            }
            district.add(listEle.baseUri());
            districtList.add(district);
        }
        //下一页
        String nextPage = "https://124.128.246.22:8090/onsaling/index_"+districtNum+".shtml?zn=all&pu=all&pn=&en=";
        districtNum++;
        //https://124.128.246.22:8090/onsaling/index_3.shtml?zn=all&pu=all&pn=&en=
//        logger.error("nextPage:{}",nextPage);
//        page.addTargetRequest(nextPage);
        page.putField("type", Constants.ProcessType.DISTRICT);
        page.putField("districtList", districtList);
    }

    @Override
    public Site getSite() {
        return site;
    }

    /**
     * 获取起始url
     * @return
     */
    public String getUrl() {
        // 门店查询页面 https://www.ele.me/place/wtw0w37dxs0r?latitude=31.032709&longitude=121.217287
        // 门店里列表json https://h5.ele.me/restapi/shopping/v3/restaurants?latitude=31.107641&longitude=121.252976&offset=0&limit=1&extras[]=activities&extras[]=tags&terminal=h5
        // 店铺json https://www.ele.me/shop/E7326872827353281855
    	/*String url = "https://www.ele.me/place/";
    	String geohash = "wtw0w37dxs0r";*/
        String url = "https://124.128.246.22:8090/onsaling/index.shtml";
//        url = "https://124.128.246.22:8090/onsaling/index_3.shtml?zn=all&pu=all&pn=&en=";
//        String url = "https://h5.ele.me/restapi/shopping/v3/restaurants?latitude=" + latitude + "&longitude=" + longitude + "&offset=0&limit=3&extras[]=activities&extras[]=tags&terminal=h5&userSSL=false";

//        String url = "http://h5.ele.me/restapi/shopping/v3/restaurants?latitude=" + latitude + "&longitude=" + longitude + "&offset=0&limit=3&extras[]=activities&extras[]=tags&terminal=h5&userSSL=false";
        return url;
    }

    public String getBaseUrl(){
        String url = "https://124.128.246.22:8090/";
        return url;
    }

    public String getTestBaseUrl(){
        String url = "https://124.128.246.22:8090/onsaling/bshow.shtml?bno=1240e465-3e78-4248-83d5-f3fd177d5cf8";
        return url;
    }

    public String getYearSaleUrl(){
        String url = "https://124.128.246.22:8090/onsaling/yearsale.shtml";
        return url;
    }

    public String getViewhouse(){
        return "https://124.128.246.22:8090/onsaling/viewhouse.shtml?fmid=e54a5b66-6fd8-4754-88e4-cb357d779e8b";
    }
    public String getViewhouse2(){
        return "https://124.128.246.22:8090/onsaling/viewhouse.shtml?fmid=4bed361e-1af0-49ce-9264-1af1b934a4ab";
    }

    public void close() {
        webDriver.close();
        WebDriver webDriver ;
        if (!webDriverQueue.isEmpty()){
            while ((webDriver = webDriverQueue.peek()) != null){
                webDriver.close();
            }
        }


    }

}
